class ViewMonitorPlugin {
  constructor() {
    this.hasOperation = false;
    this.isI18n = true;
    this.i18nList = null;
    this.callback = null;
    this.hashMap = new Map();
  }
  init(option) {
    this.callback = option.callback || null;
    this.isI18n = option.isI18n || true;
    if (!option.i18nList) {
      throw new Error('i18nList 国际化选项必须配置！')
    }
    if (this.hasOperation) {
      return;
    }
    this.i18nList = option.i18nList;
    this.hasOperation = true;
    const fragment = document.createDocumentFragment();
    const pDiv = this.handleAppendParentNode();

    const monitorList = document.querySelectorAll('*[data-monitor]');

    for (let i = 0; i < monitorList.length; i++) {
      let item = monitorList[i];
      if (!this.isInViewPort(item)) {
        break;
      }
      if (this.hashMap.has(item.dataset.monitor)) {
        continue;
      } else {
        let oNode = this.hasLabelNode(item)
        this.hashMap.set(item.dataset.monitor, oNode)
        this.handleAppendElement(oNode, pDiv);
      }
    }

    document.documentElement.style.overflowY = 'hidden';
    fragment.appendChild(pDiv);
    document.body.appendChild(fragment);
  }
  hasLabelNode(element) {
    let oNode = element
    if (element.hasChildNodes()) {
      Array.from(element.childNodes).forEach((node) => {
        if (node.nodeName === 'LABEL') {
          node.setAttribute('data-monitor', element.dataset.monitor)
          oNode = node
        }
      });
    }

    return oNode
  }
  handleAppendParentNode() {
    const pDiv = document.createElement('div');
    const { top } = document.body.getBoundingClientRect();
    pDiv.setAttribute(
      'style',
      `width: 100vw;height: 100vh;position: absolute;z-index: 99997;top: ${-top}px;left: 0; background: rgba(0, 0, 0, 0.5);`
    );

    pDiv.ondblclick = () => {
      document.documentElement.style.overflowY = 'auto';
      document.body.removeChild(pDiv);
      this.hasOperation = false;
      location.reload();
    };
    return pDiv;
  }
  handleAppendElement(item, pDiv) {
    const childDiv = document.createElement('div');
    childDiv.classList = 'edit-main';
    this.handleEditIcon(item, childDiv);
    pDiv.appendChild(childDiv);
  }
  handleEditIcon(item, pDiv) {
    const { top, left, width, height } = item.getBoundingClientRect();
    let svgContainer = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
    svgContainer.innerHTML = `<svg t="1720137828001" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="946" width="24" height="24"><path d="M128 896h768v-64H128zM256 704v-146.752l224-224L626.752 480l-224 224H256zM608 205.248L754.752 352 672 434.752 525.248 288 608 205.248z m214.624 169.408l0.032-0.032a32 32 0 0 0 0-45.248l-0.032-0.032-191.968-191.968-0.032-0.032a32 32 0 0 0-45.248 0l-0.032 0.032L192 530.752V768h237.248l393.376-393.344z" fill="#ffffff" p-id="947"></path></svg>`;
    let svgFrag = document.createDocumentFragment();
    let editIcon = svgFrag.appendChild(svgContainer.firstChild);
    editIcon.setAttribute(
      'style',
      `position: absolute;z-index: 99998; left: ${left + width / 2 - 12}px; top: ${top + height / 2 - 12}px; cursor: pointer;`
    );
    pDiv.appendChild(editIcon);

    editIcon.onclick = () => {
      if (this.isI18n) {
        this.resetOperate('i18n-content')
        editIcon.style.display = 'none';
        this.handleEditI18n(item, pDiv);
      } else {
        this.resetOperate('edit__input')
        editIcon.style.display = 'none';
        this.handleEditInput(item, pDiv);
      }
    };
  }
  handleEditInput(item, pDiv) {
    const inputWidth = 120;
    const inputHeight = 20;
    const { top, left } = this.handleLocationCalculate(
      item,
      inputWidth,
      inputHeight
    );
    const input = document.createElement('input');
    input.type = 'text';
    input.value = item.innerText || item.placeholder;
    input.setAttribute(
      'style',
      `width: ${inputWidth}px;height: ${inputHeight}px; position: absolute;z-index: 99999; left: ${left}px;top: ${top}px; display: block;`
    );
    input.className = 'edit__input';
    pDiv.appendChild(input);
    input.focus();

    input.onblur = (e) => {
      input.previousElementSibling.style.display = 'block';
      item.innerText = e.target.value;
      this.callback && this.callback(item.dataset.monitor, e.target.value);

      pDiv.removeChild(input);
    };
  }
  handleEditI18n(item, pDiv) {
    if (pDiv.getElementsByClassName('i18n-content').length > 0) {
      return pDiv.getElementsByClassName('i18n-content')[0].style.display = 'block';
    }
    const swapper = document.createElement('div');
    swapper.className = 'i18n-content';
    const cWidth =
      document.body.clientWidth || document.documentElement.clientWidth;
    const cHeight =
      document.body.clientHeight || document.documentElement.clientHeight;
    let { x, top, left } = item.getBoundingClientRect();
    if (x + 220 > cWidth) {
      left = cWidth - 220;
    }
    if (top + 120 > cHeight) {
      top = cHeight - 120;
    }

    swapper.setAttribute(
      'style',
      `width: 200px;position: absolute;z-index: 99999;top: ${top}px;left: ${left}px; background: #fff; border-radius: 4px; padding: 10px;`
    );

    for (let lang in this.i18nList) {
      const zhContent = this.createI18nFormElement(lang, this.i18nList[lang], item);
      swapper.appendChild(zhContent);
    }

    const operate = this.createI18nFormOperate(pDiv, swapper, item);
    swapper.appendChild(operate);

    pDiv.appendChild(swapper);
  }
  createI18nFormElement(lang, labelName, item) {
    const monitorKey = item.dataset.monitor;
    const i18nContent = JSON.parse(localStorage.getItem('page-info')) || {};
    const content = document.createElement('div');
    const label = document.createElement('label');
    label.setAttribute('style', 'width: 70px;display: inline-block;');
    label.textContent = labelName + ':';
    const input = document.createElement('input');
    input.setAttribute('style', 'width: 120px;');
    input.value = i18nContent[lang][monitorKey];
    input.className = `${lang}__input`;
    content.setAttribute('style', 'margin-bottom:10px;');

    content.appendChild(label);
    content.appendChild(input);

    return content;
  }
  createI18nFormOperate(pDiv, parent, item) {
    const content = document.createElement('div');
    content.setAttribute('style', 'width: 100%;text-align: center;');

    const cancel = document.createElement('button');
    cancel.setAttribute(
      'style',
      'width: 80px;height: 32px;background: #fff;border: 1px #409eff solid;color: #409eff;font-size: 14px;margin-right: 5px;'
    );
    cancel.textContent = '取消';
    cancel.onclick = () => {
      parent.previousElementSibling.style.display = 'block';
      pDiv.removeChild(parent);
    };
    content.appendChild(cancel);

    const submit = document.createElement('button');
    submit.setAttribute(
      'style',
      'width: 80px;height: 32px;background: #409eff;color: #fff;font-size: 14px;margin-left: 5px;'
    );
    submit.textContent = '提交';

    submit.onclick = () => {
      let langChange = {}
      for (const lang in this.i18nList) {
        const inputEle = parent.querySelector(`.${lang}__input`)
        langChange[lang] = inputEle.value
      }
      this.callback &&
        this.callback(item.dataset.monitor, langChange);

      parent.previousElementSibling.style.display = 'block';
      pDiv.removeChild(parent);

      // location.reload();
    };
    content.appendChild(submit);

    return content;
  }
  handleLocationCalculate(item, w, h) {
    const cWidth =
      document.body.clientWidth || document.documentElement.clientWidth;
    const iWidth = window.innerWidth;
    const sWidth = iWidth - cWidth;

    const { x, top, left, width, height } = item.getBoundingClientRect();
    let bLeft = x;
    let bRight = left;

    if (cWidth - x - width < w) {
      bRight = bRight - (cWidth - x - width) - sWidth;
    }

    if (cWidth - x < w) {
      bLeft = cWidth - w;
    }
    return { top: top + (height - h) / 4, right: bRight + width, left: bLeft };
  }
  resetOperate(className) {
    const editMains = document.getElementsByClassName(className);
    if (editMains.length > 0) {
      for (let i = 0; i < editMains.length; i++) {
        editMains[i].style.display = 'none';
      }
    }
    const editIcons = document.getElementsByClassName('icon-scada-edit');
    if (editIcons.length > 0) {
      for (let i = 0; i < editIcons.length; i++) {
        editIcons[i].style.display = 'block';
      }
    }
  }
  isInViewPort(ele) {
    const viewWidth = window.innerWidth || document.documentElement.clientWidth;
    const viewHeight =
      window.innerHeight || document.documentElement.clientHeight;
    const { top, right, bottom, left } = ele.getBoundingClientRect();
    return top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight;
  }
}

// module.exports = { ViewMonitorPlugin }
export default ViewMonitorPlugin;